﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace PivalSoft.LDMS.Data
{
    public class LDMSRepository
    {
        #region ADD METHODS

        public int AddUser(Login login)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                context.Entry<Login>(login).State = login.LoginID > 0 ? EntityState.Modified : EntityState.Added;////  context.Logins.Add(login);
                return context.SaveChanges();
            }
        }

        public int AddCourt(Court court)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                context.Entry<Court>(court).State = court.CourtID > 0 ? EntityState.Modified : EntityState.Added;//// .Courts.Add(court);
                return context.SaveChanges();
            }
        }

        public int AddContact(Contact contact)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                context.Entry<Contact>(contact).State = contact.ContactID > 0 ? EntityState.Modified : EntityState.Added;//// context.Contacts.Add(contact);
                return context.SaveChanges();
            }
        }

        public int AddCase(Case courtCase)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                context.Entry<Case>(courtCase).State = courtCase.CaseID > 0 ? EntityState.Modified : EntityState.Added;//// context.Cases.Add(courtCase);
                return context.SaveChanges();
            }
        }

        public int AddCaseHearing(CaseHearing courtCase)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                context.Entry<CaseHearing>(courtCase).State = courtCase.CaseHearingID > 0 ? EntityState.Modified : EntityState.Added;////context.CaseHearings.Add(courtCase);
                return context.SaveChanges();
            }
        }

        public int AddReference(ReferenceBook refBook)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                context.Entry<ReferenceBook>(refBook).State = refBook.RefID > 0 ? EntityState.Modified : EntityState.Added; // context.ReferenceBooks.Add(refBook);
                return context.SaveChanges();
            }
        }


        #endregion

        #region SELECT METHODS

        public Login ValidateLogin(string userName, string password)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                return context.Logins.Where(s => s.UserName == userName && s.Password == password).FirstOrDefault();

            }
        }

        public IList<Login> GetAllUsers()
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                return context.Logins.OrderBy(s => s.DisplayName).ToList();

            }
        }

        public IList<Court> GetAllCourts(int isActiveFlag)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                if (isActiveFlag == 1)
                    return context.Courts.Where(s => s.IsActive).OrderBy(s => s.CourtName).ToList();
                else
                    return context.Courts.OrderBy(s => s.CourtName).ToList();

            }
        }

        public IList<Contact> GetContactByType(int typeID)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                if (typeID == 0)
                    return context.Contacts.OrderBy(s => s.FirstName).ToList();
                else
                    return context.Contacts.Where(s => s.ContactTypeId == typeID).OrderBy(s => s.FirstName).ToList();
            }
        }

        public IList<TypeMaster> GetTypes(string code)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                if (code == string.Empty)
                    return context.TypeMasters.OrderBy(s => s.TypeName).ToList();
                else
                    return context.TypeMasters.Where(s => s.Code == code).OrderBy(s => s.TypeName).ToList();
            }
        }

        public IList<Case> GetAllCases()
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                return context.Cases.OrderBy(s => s.CaseTitle).ToList();
            }
        }

        public CaseHearing GetCaseHearByIding(int caseId)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                return context.CaseHearings.Where(s => s.CaseID == caseId).FirstOrDefault();
            }
        }

        public Case GetCaseByCaseID(int caseId)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                return context.Cases.Where(s => s.CaseID == caseId).FirstOrDefault();
            }
        }

        public List<TypeMaster> GetTypeMasters(string code)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                return context.TypeMasters.Where(t => t.Code == code).ToList();
            }
        }

        public List<TypeMaster> GetTypeMasters(List<string> codes)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                return context.TypeMasters.Where(t => codes.Contains(t.Code)).ToList();
            }
        }

        #endregion

        #region SEARCH METHODS

        public List<Login> SearchUser(List<KeyValuePair<string, string>> parameters)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                IQueryable<Login> query = context.Logins.AsQueryable();
                parameters.ForEach(p =>
                {
                    string param = p.Key.ToLower();
                    switch (param)
                    {
                        case Constants.USERNAME:
                            query = query.Where(s => p.Value == s.UserName);
                            break;
                        case Constants.DISPLAYNAME:
                            query = query.Where(s => p.Value == s.DisplayName);
                            break;
                        case Constants.ACTIVE:
                            bool active = Convert.ToBoolean(p.Value);
                            query = query.Where(s => active == s.IsActive);
                            break;
                    }
                });

                return query.ToList();
            }
        }

        public List<Contact> SearchContact(List<KeyValuePair<string, string>> parameters)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                IQueryable<Contact> query = context.Contacts.AsQueryable();
                parameters.ForEach(p =>
                {
                    string param = p.Key.ToLower();
                    switch (param)
                    {
                        case Constants.NAME:
                            query = query.Where(s => p.Value.Contains(s.FirstName) || p.Value.Contains(s.LastName));
                            break;
                        case Constants.CONTACT:
                            query = query.Where(s => p.Value.Contains(s.PrimaryContact) || p.Value.Contains(s.SecondaryContact));
                            break;
                        case Constants.ADDRESS:
                            query = query.Where(s => p.Value.Contains(s.Address1) || p.Value.Contains(s.Address2));
                            break;
                        case Constants.CITY:
                            query = query.Where(s => p.Value == s.City);
                            break;
                        case Constants.ZIP:
                            query = query.Where(s => p.Value == s.ZipCode);
                            break;
                        case Constants.EMAIL:
                            query = query.Where(s => p.Value == s.Email);
                            break;
                        case Constants.PRIMARY:
                            query = query.Where(s => p.Value == s.PrimaryContact);
                            break;
                        case Constants.SECONDARY:
                            query = query.Where(s => p.Value == s.SecondaryContact);
                            break;
                    }
                });

                return query.ToList();
            }
        }

        public List<Court> SearchCourt(List<KeyValuePair<string, string>> parameters)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                int value = 0;
                IQueryable<Court> query = context.Courts.AsQueryable();
                parameters.ForEach(p =>
                {
                    string param = p.Key.ToLower();
                    switch (param)
                    {
                        case Constants.CITY:
                            query = query.Where(s => p.Value == s.City);
                            break;
                        case Constants.ZIP:
                            query = query.Where(s => p.Value == s.ZipCode);
                            break;
                        case Constants.NAME:
                            query = query.Where(s => p.Value == s.CourtName);
                            break;
                        case Constants.STATE:
                            value = Convert.ToInt32(p.Value);
                            query = query.Where(s => value == s.StateID);
                            break;
                    }
                });

                return query.ToList();
            }
        }

        public List<ReferenceBook> SearchReference(List<KeyValuePair<string, string>> parameters)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                IQueryable<ReferenceBook> query = context.ReferenceBooks.AsQueryable();
                parameters.ForEach(p =>
                {
                    string param = p.Key.ToLower();
                    switch (param)
                    {
                        case Constants.CASE:
                            query = query.Where(s => p.Value.Contains(s.Notes));
                            break;
                        case Constants.TAG:
                            query = query.Where(s => p.Value.Contains(s.Tags));
                            break;
                        case Constants.REFDATE:
                            DateTime date = Convert.ToDateTime(p.Value);
                            query = query.Where(s => date == s.RefDate);
                            break;
                    }
                });

                return query.ToList();
            }
        }

        public List<Case> SearchCase(List<KeyValuePair<string, string>> parameters)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                int value = 0;
                IQueryable<Case> query = context.Cases.AsQueryable();
                parameters.ForEach(p =>
                {
                    string param = p.Key.ToLower();
                    switch (param)
                    {
                        case Constants.TITLE:
                            query = query.Where(s => p.Value.Contains(s.CaseTitle));
                            break;
                        case Constants.DESC:
                            query = query.Where(s => p.Value.Contains(s.CaseDescription));
                            break;
                        case Constants.COURT:
                            value = Convert.ToInt32(p.Value);
                            query = query.Where(s => value == s.CourtID);
                            break;
                        case Constants.OPPADVOCATE:
                            value = Convert.ToInt32(p.Value);
                            query = query.Where(s => value == s.OppositionAdvocateID);
                            break;
                        case Constants.OPPPARTY:
                            value = Convert.ToInt32(p.Value);
                            query = query.Where(s => value == s.OppositionPartyID);
                            break;
                        case Constants.PARTYADVOCATE:
                            value = Convert.ToInt32(p.Value);
                            query = query.Where(s => value == s.AdvocateID);
                            break;
                        case Constants.PARTY:
                            value = Convert.ToInt32(p.Value);
                            query = query.Where(s => value == s.PartyID);
                            break;
                    }
                });

                return query.ToList();
            }
        }

        public List<CaseHearing> SearchHearing(List<KeyValuePair<string, string>> parameters)
        {
            using (LDMSEntities context = new LDMSEntities())
            {
                DateTime date;
                int value = 0;
                IQueryable<CaseHearing> query = context.CaseHearings.AsQueryable();
                parameters.ForEach(p =>
                {
                    string param = p.Key.ToLower();
                    switch (param)
                    {
                        case Constants.CASE:
                            value = Convert.ToInt32(p.Value);
                            query = query.Where(s => value == s.CaseID);
                            break;
                        case Constants.PARTY:
                            query = query.Where(s => p.Value.Contains(s.Case.ContactParty.FirstName) || p.Value.Contains(s.Case.ContactParty.LastName));
                            break;
                        case Constants.HEARINGDATE:
                            date = Convert.ToDateTime(p.Value);
                            query = query.Where(s => date.Equals(s.HearingDate));
                            break;
                        case Constants.NEXTHEARING:
                            date = Convert.ToDateTime(p.Value);
                            query = query.Where(s => date == s.NextHearingDate);
                            break;
                        case Constants.OPPPARTY:
                            query = query.Where(s => p.Value.Contains(s.OppositionContact.FirstName) || p.Value.Contains(s.OppositionContact.LastName));
                            break;
                    }
                });
                return query.ToList();
            }
        }

        #endregion
        
    }
}
